package com.boot2.core.utils;

import com.boot2.core.exception.BusinessException;
import lombok.extern.apachecommons.CommonsLog;
import okhttp3.*;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author zhangweilin
 * @description: 基类，将公共部分抽出
 * @date 2018/10/25
 */
@CommonsLog
public abstract class AbstractHttpsClient extends AbstractHttpsClientCall {
    protected static String MEDIA_TYPE_JSON = "application/json; charset=utf-8"; // json请求
    protected static String MEDIA_TYPE_FORM = "application/x-www-form-urlencoded; charset=utf-8"; // 表单请求

    /**
     * @param url
     * @param headerMap
     * @param body
     * @return
     */
    protected static Map<String, Object> sendReqWithReturnHeader(String url, Map<String, String> headerMap, RequestBody body) {
        // log.info("@see"+getCurrentClassName()+"#createHttpPost,请求url:
        // "+url+",请求参数:"+body.toString());
        final Call call = getReqCall(url, headerMap, body);
        Headers headers = null;
        String result = null;
        try {
            Response response = call.execute();
            headers = response.headers();
            result = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            throw new BusinessException("请求失败,url: " + url, e);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>(2);
        resultMap.put("result", result);
        resultMap.put("headers", headers);
        return resultMap;
    }

    protected static String sendReq(String url, RequestBody body) throws IOException {
        log.info("请求url: " + url + ",请求参数:" + body.toString());
        final Request request = new Request.Builder().url(url).post(body).build();

        // 创建请求对象
        final Call call = getHttpInstance().newCall(request);
        Response response = call.execute();
        String result = response.body().string();
        return result;
    }

    protected static void sendReqAsync(String url, RequestBody body, HttpsClient.AbstractCallback abstractCallback) {
        log.info("请求url: " + url + ",请求参数:" + body.toString());
        final Request request = new Request.Builder().url(url).post(body).build();
        // 创建请求对象
        final Call call = getHttpInstance().newCall(request);
        call.enqueue(abstractCallback);
    }

    protected static String sendReq(String url, Map<String, String> headerMap, RequestBody body) throws IOException {
        final Call call = getReqCall(url, headerMap, body);
        Response response = call.execute();
        String result = response.body().string();
        return result;
    }

    /**
     * 异步请求
     *
     * @param url
     * @param headerMap
     * @param body
     * @param abstractCallback
     */
    protected static void sendReqAsync(String url, Map<String, String> headerMap, RequestBody body, HttpsClient.AbstractCallback abstractCallback) {
        final Call call = getReqCall(url, headerMap, body);
        call.enqueue(abstractCallback);
    }

    protected static Call getReqCall(String url, Map<String, String> headerMap, RequestBody body) {
        log.info("请求url: " + url + ",请求参数:" + body.toString());
        Request.Builder builder = new Request.Builder();
        if (null != headerMap) {
            Set<Map.Entry<String, String>> entrySet = headerMap.entrySet();
            for (Map.Entry<String, String> entry : entrySet) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        final Request request = builder.url(url).post(body).build();
        // 创建请求对象
        return getHttpInstance().newCall(request);
    }

    /**
     * @param url
     * @param body
     * @return
     */
    protected static Map<String, Object> sendReqWithReturnHeader(String url, RequestBody body) {
        // log.info("@see"+getCurrentClassName()+"#createHttpPost,请求url:
        // "+url+",请求参数:"+body.toString());
        log.info("请求url: " + url + ",请求参数:" + body.toString());
        final Request request = new Request.Builder().url(url).post(body).build();
        // 创建请求对象
        final Call call = getHttpInstance().newCall(request);
        Headers headers = null;
        String result = null;
        try {
            Response response = call.execute();
            headers = response.headers();
            result = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            throw new BusinessException("请求失败,url: " + url, e);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>(2);
        resultMap.put("result", result);
        resultMap.put("headers", headers);
        return resultMap;
    }

//    /**
//     * @description convertStreamToString @Author liangjl @Date 2018年2月9日
//     * 下午3:02:00 @param is @return 参数 @return String 返回类型 @throws
//     */
//    protected static String convertToString(InputStream is) {
//        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
//        StringBuilder buffer = new StringBuilder();
//        String line = null;
//        try {
//            while ((line = reader.readLine()) != null) {
//                buffer.append(line + "\r");
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                is.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        return buffer.toString();
//    }

    /**
     * @param contentType 请求头header属性
     * @param params      请求参数
     * @return RequestBody 返回类型
     * @description 组装参数
     * @Date 2017年7月10日 下午5:48:13
     */
    protected static RequestBody createRequestBody(String contentType, Map<String, Object> params) {
        MediaType type = MediaType.parse(contentType);
        String paramStrs = concatParams(params).toString();
        RequestBody requestBody = RequestBody.create(type, paramStrs);
        return requestBody;
    }


    /**
     * @param url
     * @param params
     * @return
     */
    protected static String concatParams(String url, Map<String, ? extends Object> params) {
        StringBuilder stringBuilder = concatParams(params);
        url = url + "?" + stringBuilder.toString();
        return url;
    }

    /**
     * @description TrustAllCerts
     * @ClassName TrustAllCerts
     * @Date 2018年2月9日 下午3:15:23
     * @Author liangjl
     * @Copyright (c) All Rights Reserved, 2018.
     */
    protected static class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }


    /**
     * 回调处理消息
     */
    public abstract static class AbstractCallback implements Callback {
        @Override
        public void onFailure(Call call, IOException e) {
            onFailure(e);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String result = response.body().string();
            onResponse(result);
        }

        public void onResponse(String result) {

        }

        public void onFailure(IOException e) {

        }
    }


    /**
    * @author zhangweilin
    * @date 2018/10/25 6:22
    * @description:  验证所有主机
    */
    protected static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}
